﻿using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace SharePointRsync
{
    public class SharePointRsyncJob : SPFirstAvailableServiceJobDefinition
    {
        [Persisted]
        private string _webURL, _listID, _itemID = null;

        [Persisted]
        private bool _forceOverwrite = false;

        public SharePointRsyncJob()
            : base()
        {
        }

        public SharePointRsyncJob(string jobName, SPService service)
            : base(jobName, service)
        {
        }

        public SharePointRsyncJob(string jobName, SPService service, string weburl, string listid, bool forceOverwrite)
            : base(jobName, service)
        {
            _webURL = weburl;
            _listID = listid;
            _itemID = null;
            _forceOverwrite = forceOverwrite;
        }

        public SharePointRsyncJob(string jobName, SPService service, string weburl, string listid, string itemid, bool forceOverwrite)
            : base(jobName, service)
        {
            _webURL = weburl;
            _listID = listid;
            _itemID = itemid;
            _forceOverwrite = forceOverwrite;
        }

        public override void Execute(SPJobState jobState)
        {
            using (SPSite site = new SPSite(_webURL))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    SPListItemCollection listItems = web.Lists[new Guid(_listID)].Items;
                    SPFieldCollection syncListFieldCols = web.Lists[new Guid(_listID)].Fields;

                    if (_itemID == null) //whole list copy
                    {
                        foreach (SPListItem item in listItems)
                        {
                            syncItem(syncListFieldCols, item);
                        }
                    }
                    else //single item copy
                    {
                        SPListItem item = listItems.GetItemById(Int32.Parse(_itemID));
                        syncItem(syncListFieldCols, item);
                    }
                }
            }
        }

        private void syncItem(SPFieldCollection syncListFieldCols, SPListItem item)
        {
            try
            {
                SPFieldCollection sourceListfieldCols = null;
                UpdateStatus(item, "Pending", null);
                string syncFrom = string.Empty;

                try
                {
                    syncFrom = new SPFieldUrlValue(item["SyncFrom"].ToString()).Url;
                }
                catch (Exception ex)
                {
                    throw new Exception("'Sync From' path is invalid");
                }

                if (syncFrom.StartsWith("http"))
                {
                    SPList syncFromList = SyncJobManager.GetListByUrl(syncFrom);
                    sourceListfieldCols = syncFromList.Fields;
                }

                Sync sync = new Sync(item, syncListFieldCols, sourceListfieldCols, _forceOverwrite);
            }
            catch (Exception ex)
            {
                UpdateStatus(item, "Failed", ex.Message);
            }
        }

        private static void UpdateStatus(SPListItem item, string status, string log)
        {
            item["SyncStatus"] = status;
            if (log != null)
            {
                item["SyncLog"] = log;
            }
            item.SystemUpdate();
        }
    }
}
